home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / MotifApp / Extras / TicTacToe / Board.C next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  4.0 KB  |  163 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //////////////////////////////////////////////////////////////////////////////
  3. //         This example code is from the book:
  4. //
  5. //           Object-Oriented Programming with C++ and OSF/Motif
  6. //         by
  7. //           Douglas Young
  8. //           Prentice Hall, 1992
  9. //           ISBN 0-13-630252-1    
  10. //
  11. //         Copyright 1991 by Prentice Hall
  12. //         All Rights Reserved
  13. //
  14. //  Permission to use, copy, modify, and distribute this software for 
  15. //  any purpose except publication and without fee is hereby granted, provided 
  16. //  that the above copyright notice appear in all copies of the software.
  17. ///////////////////////////////////////////////////////////////////////////////
  18. //////////////////////////////////////////////////////////////////////////////
  19.  
  20.  
  21. /////////////////////////////////////////////////////////////
  22. // Board.C
  23. /////////////////////////////////////////////////////////////
  24. #include "Board.h"
  25.  
  26. // Array of all possible winning patterns. 1 indicates a win
  27.  
  28. int Board::_winningBits[8][9] = {
  29. { 1, 0, 0, 1, 0, 0, 1, 0, 0 },
  30. { 0, 1, 0, 0, 1, 0, 0, 1, 0 },
  31. { 0, 0, 1, 0, 0, 1, 0, 0, 1 },
  32. { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
  33. { 0, 0, 0, 1, 1, 1, 0, 0, 0 },
  34. { 0, 0, 0, 0, 0, 0, 1, 1, 1 },
  35. { 1, 0, 0, 0, 1, 0, 0, 0, 1 },
  36. { 0, 0, 1, 0, 1, 0, 1, 0, 0 },
  37. };
  38.  
  39. Board::Board()
  40. {
  41.     clear();  // Initialize the board
  42. }
  43.  
  44. void Board::clear()
  45. {
  46.     // NOBODYYET doubles as an indication that no one has won
  47.     // and that no move has been recorded for a square
  48.     
  49.     for ( int i = 0; i < 9; i++ )
  50.     _state[i] = NOBODYYET;
  51. }
  52.  
  53. MoveStatus Board::recordMove ( int position, markType mark )
  54. {
  55.     if ( _state[position] != NOBODYYET ) // Make sure square is empty
  56.     return illegalMove;
  57.     
  58.     // Record the move, and report it as legal
  59.     
  60.     _state[position] = mark;
  61.     return validMove;
  62. }
  63.  
  64. int *const Board::freeSquares ( int &numFree )
  65. {
  66.     int i, j;
  67.     
  68.     // Build up a list of the indexes (0-8) of free squares
  69.     
  70.     for ( j = 0, i = 0; i < 9; i++ )
  71.     if ( _state[i] == NOBODYYET )
  72.         _freeList[j++] = i;
  73.     numFree = j;
  74.     return _freeList;
  75. }
  76.  
  77. int Board::numFreeSquares()
  78. {
  79.     int i, count;
  80.     
  81.     // Look for and count unmarked squares
  82.     
  83.     for ( count = 0, i = 0; i < 9; i++ )
  84.     if ( _state[i] == NOBODYYET )
  85.         count++;
  86.     return count;
  87.     
  88. }
  89.  
  90. markType Board::whoHasWon()
  91. {
  92.     int i, j;
  93.     
  94.     // Check the state of the board to see if anyone has won
  95.     
  96.     for ( i = 0; i < 8; i++ )
  97.     {
  98.     int xcount = 0;  // Initialize to no X's, no O's
  99.     int ocount = 0;
  100.     
  101.     _winningPattern = _winningBits[i];     // Remember in case of a win
  102.     
  103.     for ( j = 0; j < 9; j++ )     // Test each winning pattern
  104.         if ( _winningBits[i][j] )
  105.         if ( _state[j] == OO )
  106.             ocount++;          // Count O's in winning squares
  107.         else if ( _state[j] == XX )                    
  108.             xcount++;          // Count X's in winning squares
  109.     
  110.     if ( ocount == 3 )   // If either mark occupied 3 squares
  111.         return OO;       // then return the winner
  112.     if ( xcount == 3 )
  113.         return XX;
  114.     }
  115.     
  116.     if ( numFreeSquares() > 0 )  // If no one won, report a tie or
  117.     return NOBODYYET;        // continue the game, as appropriate
  118.     else
  119.     return TIE;
  120. }
  121.  
  122.  
  123. // Function that supports one move look-ahead
  124. // Return the first move that could win for the given 
  125. // player, if there is one
  126.  
  127. int Board::winningMove ( markType player )
  128. {
  129.     int i, j;
  130.    
  131.     
  132.     for ( i = 0; i < 8; i++ )
  133.     {
  134.     int count    = 0;  // Initialize to no matches
  135.     int opponent = 0;
  136.     
  137.     for ( j = 0; j < 9; j++ )     // Test each winning pattern
  138.         if ( _winningBits[i][j] )
  139.             if ( _state[j] == player )
  140.             count++;          
  141.             else if ( _state[j] != NOBODYYET )
  142.             opponent++;
  143.  
  144.     // If the requested player has two in a row, and the
  145.     // remaining square in that row is blank, return the
  146.     // move that could win for that player.
  147.  
  148.     if ( count == 2 && opponent == 0)   
  149.     {
  150.         int index;
  151.  
  152.         for ( index = 0; index < 9 ; index++ )
  153.         {
  154.         if ( _winningBits[i][index] &&
  155.              !_state[index] )
  156.             return index;
  157.         }
  158.     }
  159.     }
  160.  
  161.     return -1;
  162. }
  163.